Skip to content

Conversation

@vezwork
Copy link
Collaborator

@vezwork vezwork commented Sep 24, 2025

New in Positron: pressing ctrl+enter with your cursor in a multiline R statement executes the whole statement.

Screenshot 2025-09-24 at 3 55 59 PM

Before it would only execute the current line.

Note: this fix relies on Positron's vscode.executeStatementRangeProvider command and does not work in VSCode. I was attempting to get this working in VSCode by creating a virtual doc for the code block, setting your cursor in the virtual doc, and running a cell executor on the virtual doc. That did not work out because I don't know how to set your cursor's position in a virtual doc and cell execution commands don't take positions as arguments.

addresses posit-dev/positron#7709

@vezwork vezwork requested a review from juliasilge September 24, 2025 19:59
@vezwork vezwork changed the title use statementRangeProvider in Positron to execute statements at cursor in VE in VE use statementRangeProvider in Positron to execute statements at cursor Sep 24, 2025
@vezwork vezwork changed the title in VE use statementRangeProvider in Positron to execute statements at cursor in VE use Positron's statementRangeProvider to execute statements at cursor Sep 24, 2025
@vezwork vezwork changed the title in VE use Positron's statementRangeProvider to execute statements at cursor in VE use Positron's statementRangeProvider to execute statements Sep 24, 2025
@cscheid
Copy link
Contributor

cscheid commented Sep 24, 2025

I think it's ok to prioritize Positron fixes and leave the VSC fix open for a community PR if there's an approach there that would work.

@vezwork vezwork requested a review from cscheid September 24, 2025 20:50
@juliasilge
Copy link
Collaborator

juliasilge commented Sep 24, 2025

This is really exciting to see! 🎉

I think there is a bit of improvement to do in terms of where the cursor goes in the visual editor after using these. I see that you said there is some difficulty about setting the cursor position in the visual editor 😬 so it's possible this is a big challenge. Take a look at what I mean:

---
title: "Diamond sizes"
format: html
---

```{r}
library(tidyverse)

smaller <- diamonds |>
  filter(carat <= 2.5)
```

  • In the source editor, put your cursor at library
  • Use Cmd+Enter to step through the lines, including the multiline R statement (notice where your cursor goes after each statement execution
  • Switch to the visual editor and put your cursor back at library
  • Use Cmd+Enter to try to step through the lines (notice that the cursor doesn't advance enough, which feels especially weird on the empty line)

I also wanted to ask about Python, because I don't see the Python statement range provider being applied, I think? Here is an example to look at:

---
title: "Quarto Basics"
format: html
---

## Matplotlib

For a demonstration of a line plot on a polar axis, see @fig-polar.

```{python}
#| label: fig-polar
#| fig-cap: "A line plot on a polar axis"

import numpy as np
import matplotlib.pyplot as plt

r = np.arange(0, 2, 0.01)
theta = 2 * np.pi * r
fig, ax = plt.subplots(
    subplot_kw = {'projection': 'polar'}
    )
ax.plot(theta, r)
ax.set_rticks([0.5, 1, 1.5, 2])
ax.grid(True)
plt.show()
```

  • In the source editor, put your cursor at import numpy
  • Use Cmd+Enter to step through the lines, including the multiline Python statement (notice where your cursor goes after each statement execution
  • Switch to the visual editor and pur your cursor back at import numpy
  • Use Cmd+Enter to try to step through the lines (notice it executes the whole cell, not line by line)

@vezwork
Copy link
Collaborator Author

vezwork commented Sep 25, 2025

I think there is a bit of improvement to do in terms of where the cursor goes in the visual editor after using these. I see that you said there is some difficulty about setting the cursor position in the visual editor 😬 [..]

I should be able to set the cursor in the visual editor! The cursor placement problem I was having wasn't visual editor specific, it was virtual doc specific.

I will try to improve where the cursor goes after running ctrl+enter.

Aside, to elaborate on the virtual doc + cursor problem I was facing: it would be nice to unify execution in the visual editor and the source editor by creating a virtual doc for the current code block, placing a cursor in the virtual doc, and running the relevent execution-at-cursor command in that virtual doc. Unfortunately, I think virtual docs are just files and are not "open" in an editor, so they don't have a cursor associated with them.

@vezwork
Copy link
Collaborator Author

vezwork commented Sep 26, 2025

I also wanted to ask about Python, because I don't see the Python statement range provider being applied, I think? Here is an example to look at:

Heard and seen! Thanks for the great example. Indeed the python statement range provider does not seem to be being applied. Also looking at this.

@vezwork
Copy link
Collaborator Author

vezwork commented Sep 26, 2025

Q: In the source editor, when you Cmd+Enter to step through executing the statements in a cell, what logic does it use to find the index of the start of the next statement?

A: @sharon-wang found it for me: https://github.com/posit-dev/positron/blob/main/src/vs/workbench/contrib/positronConsole/browser/positronConsoleActions.ts#L428 in the advanceStatement function.

I will copy this logic into the Quarto LSP. Maybe ideally Positron would provide a command like "vscode.executeStatementRangeProviderAndGetNextStatementPosition" that returns both a StatementRange and a Position of the subsequent statement so the logic wouldn't have to be duplicated?

@juliasilge
Copy link
Collaborator

juliasilge commented Sep 29, 2025

I think this was only applying to R documents because of this here:

if (selection.length <= 0 && !isKnitrDocument(editor.document, this.engine_)) {


What happens in the source editor is something like this:

  • Positron says, "I have a quarto document and I need a statement range provider for it"
  • Quarto extension says, "I have one of those":

return hooks.languages.registerStatementRangeProvider('quarto',

  • Positron says, "OK, I want you to give me the statement range at position X"
  • Quarto extension say, "I will do that":

async provideStatementRange(

  • Quarto extension fulfills getStatementRange() by executing vscode.executeStatementRangeProvider for the virtual doc (i.e. it asks Positron for the statement range for the underlying virtual doc, since Positron has statement range providers for Python and R):

"vscode.executeStatementRangeProvider",

So it goes back and forth a fair amount!

I think you will want to set up request forwarding in the visualEditorServer function in connection.ts, in codeViewServerMethods; I think what needs to happen for a bunch of the LSP methods (for the statement range provider, F1 help, signature help, etc) is request forwarding. My understanding is that piping through this LSP functionality new to the visual editor will be similar to how completions are piped through.

You can see what LSP functionality the source editor has with all the "providers" in here:

export async function activateLsp(

I don't think my changes to `codeViewSetBlockSelection` work. It seems that `navigateToPos` does not work inside codeMirror? That must be why only "nextline" works in the command - it doesn't use `navigateToPos` it uses a special codeView thing.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants